import { Ref, ref } from 'vue'

import { IPageResult } from '@/http/types/base'

type PaginationFunc<T, K> = (
  currentPage: number,
  pageSize: number,
  params: K,
) => Promise<IPageResult<T>>
export default function usePagination<T, K extends Object>(
  pagedFunction: PaginationFunc<T, K>,
  params: Ref<K>,
  defaultSetting: {
    defaultSort: string
    defaultPageSize: number
  } = {
    defaultSort: '',
    defaultPageSize: 10,
  },
) {
  const DEFAULT_SORT = defaultSetting.defaultSort || ''
  const DEFAULT_PAGE_SIZE = defaultSetting.defaultPageSize || 10

  const paginationData = ref({
    total: 0,
    pageSize: DEFAULT_PAGE_SIZE,
    currentPage: 1,
  })
  const isLoading = ref(false)
  const sort = ref(DEFAULT_SORT)
  const tableData = ref<Array<T>>([]) as Ref<T[]>

  const getTableData = async () => {
    isLoading.value = true
    const res = await pagedFunction(
      paginationData.value.currentPage,
      paginationData.value.pageSize,
      {
        sorting: sort.value,
        ...params.value,
      },
    ).finally(() => {
      isLoading.value = false
    })
    tableData.value = res.items
    paginationData.value.total = res.totalCount
  }
  const handleSearch = () => {
    paginationData.value.currentPage = 1
    getTableData()
  }

  const handleSortChange = ({ prop, order }: any) => {
    let sortStr
    if (order === 'descending') {
      sortStr = `${prop} desc`
    } else if (order === 'ascending') {
      sortStr = `${prop} asc`
    } else {
      sortStr = DEFAULT_SORT
    }
    sort.value = sortStr
    handleSearch()
  }

  return {
    tableData,
    paginationData,
    isLoading,
    sort,
    getTableData,
    handleSearch,
    handleSortChange,
  }
}
